﻿using Microsoft.Phone.Shell;
using Newtonsoft.Json;
using Reuse.PCL.Services;
using System.IO.IsolatedStorage;
using System.Threading.Tasks;

namespace Reuse.WP8.Services {

	/// <summary>
	/// This service can help you use temporary and persistent storage, serializes objects to JSON strings and stores and retrieves in and from Application State and Isolated Storage
	/// </summary>
	public class StateService : IStateService {

		/// <summary>
		/// Gets objects from temporary Application State or persistent Application Storage
		/// </summary>
		/// <typeparam name="T">Type of the object in the storage</typeparam>
		/// <param name="key">Key that identifies object</param>
		/// <param name="isIsolatedStorage">True when retrieving from Application Storage, false when retrieving from Application State</param>
		/// <returns>The object retrieved from storage</returns>
		public T GetState<T>( string key, bool isIsolatedStorage = false ) {
			if ( !isIsolatedStorage ) {
				if ( !PhoneApplicationService.Current.State.ContainsKey( key ) ) {
					return default( T );
				}

				return (T)PhoneApplicationService.Current.State[key];
			} else {
				if ( IsolatedStorageSettings.ApplicationSettings.Contains( key ) ) {
					string serializedObject = IsolatedStorageSettings.ApplicationSettings[key].ToString();
					return Deserialize<T>( serializedObject );
				}

				return default( T );
			}
		}

		/// <summary>
		/// Stores object in temporary Application State or persistent Application Storage
		/// </summary>
		/// <param name="key">Key to identify the object</param>
		/// <param name="value">Object to store</param>
		/// <param name="isIsolatedStorage">True when storing to Application Storage, false when storing to Application State</param>
		public void SetState( string key, object value, bool isIsolatedStorage = false ) {
			if ( !isIsolatedStorage ) {
				if ( PhoneApplicationService.Current.State.ContainsKey( key ) ) {
					PhoneApplicationService.Current.State.Remove( key );
				}
				PhoneApplicationService.Current.State.Add( key, value );
			} else {
				string serializedObject = Serialize( value );
				if ( IsolatedStorageSettings.ApplicationSettings.Contains( key ) ) {
					IsolatedStorageSettings.ApplicationSettings.Remove( key );
					IsolatedStorageSettings.ApplicationSettings.Save();
				}
				IsolatedStorageSettings.ApplicationSettings.Add( key, serializedObject );
				IsolatedStorageSettings.ApplicationSettings.Save();
			}
		}

		private static T Deserialize<T>( string jsonString ) {
			return JsonConvert.DeserializeObject<T>( jsonString );
		}
		private static string Serialize( object objectToSerialize ) {
			return JsonConvert.SerializeObject( objectToSerialize );
		}


		public void RegisterAppFrame( object frame ) {
			throw new System.NotImplementedException();
		}

		public Task RestoreState() {
			return Task.Factory.StartNew( () => { } );
		}


		public Task SaveState() {
			return Task.Factory.StartNew( () => { } );
		}


		public System.Collections.Generic.Dictionary<string, object> SessionStateForFrame( object frame ) {
			throw new System.NotImplementedException();
		}
	}
}
